﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;

namespace Quest
{
    class Game
    {
        public List<Enemy> Enemies;
        public Weapon WeaponInRoom;
        private Player player;
        public Point PlayerLocation { get { return player.Location; } }
        public int PlayerHitPoints { get { return player.HitPoints; } }
        public List<Weapons> PlayerWeapons { get { return player.Weapons; } }
        private int level = 0;
        public int Level { get { return level; } }
        private const int maxLevel = 8;
        public int MaxLevel { get { return maxLevel; } }
        
        private Rectangle boundaries;
        public Rectangle Boundaries { get { return boundaries; } }

        private List<Type> allEnemies = new List<Type>();// { typeof(Bat), typeof(Ghost), typeof(Ghoul) };// added by me
        public List<Type> AllEnemies { get { return allEnemies;  } }

        // enhancement #1: Make the enemies smarter
        private Dictionary<Type, Levels> enemiesLevels=  new Dictionary<Type, Levels>();
        public Dictionary<Type, Levels> EnemiesLevels { get { return enemiesLevels; } }

        // enhancement #1: Make the enemies smarter

        public Game(Rectangle boundaries)
        {
            BuildEnemiesList();
            FormSetLevels MyForm = new FormSetLevels(AllEnemies, ref enemiesLevels);
            MyForm.ShowDialog();

            this.boundaries = boundaries;
            player = new Player(this, new Point(boundaries.Left + 10, boundaries.Top + 70));
        }

        public void Move(Direction direction, Random random)
        {
            player.Move(direction);
            foreach (Enemy enemy in Enemies)
                enemy.Move(random);
        }

        

        public void Equip(Weapons weaponName)
        {
            player.Equip(weaponName);
        }

        public bool CheckPlayerInventory(Weapons weaponName) 
        {
            return PlayerWeapons.Contains(weaponName);
        }

        public void HitPlayer(int maxDamage, Random random) 
        {
            player.Hit(maxDamage, random);
        }

        public void IncreasePlayerHealth(int health, Random random)
        {
            player.IncreaseHealth(health, random);
        }

        public void Attack(Direction direction, Random random)
        {
            player.Attack(direction, random);
            foreach (Enemy enemy in Enemies)
                enemy.Move(random);
        }

        private Point GetRandomLocation(Random random)
        {
            return new Point(boundaries.Left + random.Next(boundaries.Right / 10 - boundaries.Left / 10) * 10,
            boundaries.Top + random.Next(boundaries.Bottom / 10 - boundaries.Top / 10) * 10);
        }

        private void BuildEnemiesList()
        {
            foreach (Enemies enemy in Enum.GetValues(typeof(Enemies)))
                AllEnemies.Add(getEnemyType(enemy.ToString()));
        }
        
        public Enemy getEnemyInGame(Type enemyToGet)
        {
            foreach (Enemy enemy in Enemies)
                if (enemy.GetType() == enemyToGet)
                    return enemy;
            return null;
        }

        public Type getEnemyType(string enemyNameToGet)
        {
            Type myType = Type.GetType(typeof(Game).Namespace.ToString() + "." + enemyNameToGet);
            return myType;
        }

        //public bool CheckEnemyNameInGame(string enemyName)
        //{
        //    foreach (Enemy enemy in Enemies)
        //        if (enemy.GetType().Name == enemyName)
        //            return true;
        //    return false;
        //}

        public void NewLevel(Random random)
        {
            NewLevel(random, false, false);
        }

        public void NewLevel(Random random, bool restartGame, bool repeatLevel)
        {

            if (repeatLevel)
                player.restoreLastData();
            else
            {
                if (restartGame)
                {
                    player = new Player(this, new Point(boundaries.Left + 10, boundaries.Top + 70));
                    level = 0;
                }
                level++;
            }
            

            switch (level)
            {
                case 1:
                    Enemies = new List<Enemy>();
                    Enemies.Add(new Bat(this, GetRandomLocation(random),EnemiesLevels[typeof(Bat)]));
                    WeaponInRoom = new Sword(this, GetRandomLocation(random));
                    break;

                case 2:
                    Enemies = new List<Enemy>();
                    Enemies.Add(new Ghost(this, GetRandomLocation(random), EnemiesLevels[typeof(Bat)]));
                    WeaponInRoom = new BluePotion(this, GetRandomLocation(random));
                    break;

                case 3:
                    Enemies = new List<Enemy>();
                    Enemies.Add(new Ghoul(this, GetRandomLocation(random), EnemiesLevels[typeof(Ghoul)]));
                    WeaponInRoom = new Bow(this, GetRandomLocation(random));
                    break;

                case 4:
                    Enemies = new List<Enemy>(){
                    new Bat(this, GetRandomLocation(random),EnemiesLevels[typeof(Bat)]),
                    new Ghost(this, GetRandomLocation(random),EnemiesLevels[typeof(Ghost)])
                    };
                    if (CheckPlayerInventory(Weapons.Bow))
                        if (!(CheckPlayerInventory(Weapons.BluePotion)))
                            WeaponInRoom = new BluePotion(this, GetRandomLocation(random));
                        else
                            WeaponInRoom = new Bow(this, GetRandomLocation(random));
                    break;

                case 5:
                    Enemies = new List<Enemy>(){
                    new Bat(this, GetRandomLocation(random),EnemiesLevels[typeof(Bat)]),
                    new Ghost(this, GetRandomLocation(random),EnemiesLevels[typeof(Ghost)])
                    };
                    WeaponInRoom = new RedPotion(this, GetRandomLocation(random));
                    break;

                case 6:
                    Enemies = new List<Enemy>(){
                    new Ghost(this, GetRandomLocation(random),EnemiesLevels[typeof(Ghost)]),
                    new Ghoul(this, GetRandomLocation(random),EnemiesLevels[typeof(Ghoul)])
                    };
                    WeaponInRoom = new Mace(this, GetRandomLocation(random));
                    break;

                case 7:
                    Enemies = new List<Enemy>(){
                    new Bat(this, GetRandomLocation(random),EnemiesLevels[typeof(Bat)]),
                    new Ghost(this, GetRandomLocation(random),EnemiesLevels[typeof(Ghost)]),
                    new Ghoul(this, GetRandomLocation(random),EnemiesLevels[typeof(Ghoul)])
                    };
                    if (CheckPlayerInventory(Weapons.Mace))
                        if (!(CheckPlayerInventory(Weapons.RedPotion)))
                            WeaponInRoom = new RedPotion(this, GetRandomLocation(random));
                        else
                            WeaponInRoom = new Mace(this, GetRandomLocation(random));
                    break;

                case 8:
                    ////MessageBox.Show("You won!");
                    //Application.Exit();
                    break;
            }
            player.saveCurrentData();
        }


    }
}
